package ejb;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.functors.TruePredicate;
import org.apache.log4j.Level;
import org.apache.log4j.Logger;

import util.XMLWriter;
import bean.ArtPendiente;
import bean.Articulo;
import bean.EnvioTienda;
import bean.ArtPendiente.EstadoEnvio;
import ejbInterfaces.AdministradorEnvioTiendaBeanLocal;

/**
 * Session Bean implementation class AdministradorArticulosBean
 */
@Stateless
public class AdministradorEnvioTiendaBean implements
		AdministradorEnvioTiendaBeanLocal {

	@PersistenceContext(unitName = "MyDatabase")
	EntityManager em;
	private static final long serialVersionUID = 1769272505784539712L;
	private List<Articulo> envios;
	static Logger logger = Logger.getLogger(AdministradorEnvioTiendaBean.class);

	/**
	 * 
	 * Default constructor.
	 */
	public void ejbCreate() {
	}

	public AdministradorEnvioTiendaBean() {
		envios = new ArrayList<Articulo>();
	}

	@SuppressWarnings("unchecked")
	public boolean generarEnviosXML(List<EnvioTienda> listaEnvios) {
		boolean resultado = false;
		//clono la lista
		List<EnvioTienda> listaDuplicada = (List)CollectionUtils.select(listaEnvios,TruePredicate.getInstance());
		int cont = 1;
		try {
			if (listaEnvios != null && !listaEnvios.isEmpty()) {

				//Asigno iterators a ambas listas
				Iterator<EnvioTienda> it = listaEnvios.iterator();
				Iterator<EnvioTienda> itd = listaDuplicada.iterator();
				
				//recorro la lista original
				while(it.hasNext()){
					EnvioTienda et = (EnvioTienda) it.next();
					//Agarro el primer elemento (para buscar otros que se puedan incluir como articulos del mismo EnvT)
					List<EnvioTienda> listaAgrupadora = new ArrayList<EnvioTienda>();
					
					//actualizo el iterator
					itd = listaDuplicada.iterator();
					while(itd.hasNext()){
						EnvioTienda etd = (EnvioTienda) itd.next();
						//Si TiendaID y SolDistID son iguales, los puedo incluir como articulos en el mismo XML
						if((etd.getTiendaId() == et.getTiendaId()) && (etd.getNumSolDist() == et.getNumSolDist())){
							listaAgrupadora.add(etd);
							itd.remove();
						}
					}
					
					if(listaAgrupadora.size()>0){
						//Seteo los parametros que son fijos (idCentro) o autogenerados (Palc y numEnvT)
						int idCentro = 3;
						int numEnvt = Integer.valueOf(String.valueOf(11).concat(String.valueOf(cont)));
						//La dejo en 0 porque acordamos eso con uno de los changos via mail
						int numPalc = 0;
						
						//Una vez que tengo armada la lista de los articulos que pueden ser incluidos en un mismo EnvT, genero XML.
						XMLWriter.getInstance().writeEnvT(numEnvt, idCentro, et.getTiendaId(), et.getNumSolDist(), numPalc, listaAgrupadora);
						//Y agrego el envio a la tabla de EnvioTienda
						this.registrarEnvioDB(numEnvt, idCentro, et.getTiendaId(), et.getNumSolDist(), numPalc, listaAgrupadora);
						cont++;
					}
				}	
				//Una vez generados los XML, actualizo los datos en la DB
				resultado = actualizarEnvDB();
			}
		} catch (Exception e) {
			logger.log(Level.ERROR, "Error generando Envio a Tienda", e);
			resultado = false;
			e.printStackTrace();
			return resultado;
		}
		return resultado;
	}

	//Metodo que registra el EnvT generado en la DB
	private void registrarEnvioDB(int numEnvt, int centroId, int tiendaId, int numSolDist, int numPalc, List<EnvioTienda> listaAgrupadora){
		for(EnvioTienda e : listaAgrupadora)
		{
			EnvioTienda env = new EnvioTienda();
			env.setTiendaId(tiendaId);
			env.setNumSolDist(numSolDist);
			env.setCentroId(centroId);
			//La dejo en 0 porque acordamos eso con uno de los changos via mail
			env.setPalc(numPalc);
			env.setNumEnvio(numEnvt);
			env.setReferencia(e.getReferencia());
			env.setCantidad(e.getCantidad());
			
			//Persisto directamente porque nunca voy a agregar un envio nuevo con el mismo SolDist
			em.persist(env);
		}
	}
	
	//Metodo privado que se llama despues de generar los XML
	private boolean actualizarEnvDB() {
		boolean res = false;
		List<ArtPendiente> listaPendientes = new ArrayList<ArtPendiente>();

		// Borro los elementos enviados y registro los envios generados
		Query query = em.createQuery("from ArtPendiente where estado = :status");
		query.setParameter("status", EstadoEnvio.LISTO);
		listaPendientes = query.getResultList();
		
		//lomanto la concha de tu madre, un Envio a tienda no es un ArtPendiente
		for(ArtPendiente e : listaPendientes){
			em.remove(e);
		}
		// TODO: glomanto Al super pedo, despues encontrar manera de validar
		res = true;
		return res;
	}

	public List<EnvioTienda> obtenerEnviosATiendas() {
		List<EnvioTienda> envios = new ArrayList<EnvioTienda>();
		List<ArtPendiente> enviosTemp = new ArrayList<ArtPendiente>();

		Query query = em.createQuery("from ArtPendiente where estado = :status");
		query.setParameter("status", EstadoEnvio.LISTO);
		enviosTemp = query.getResultList();

		for (int i = 0; i < enviosTemp.size(); i++) {
			// Recorro la lista de ArtPendientes y armo mi lista de EnvioTienda
			EnvioTienda envio = new EnvioTienda();
			envio.setTiendaId(enviosTemp.get(i).getIdTienda());
			envio.setNumSolDist(enviosTemp.get(i).getNumSolDist());
			envio.setReferencia(enviosTemp.get(i).getReferencia());
			envio.setCantidad(enviosTemp.get(i).getCantidad());
			envio.setCentroId(11);
			envio.setPalc(0);
			// El numero de envio lo armo con mi ID(lo appendeo en el JSP) de
			// centro mas el ID de la tienda por ahora
			envio.setNumEnvio(enviosTemp.get(i).getIdTienda());
			envios.add(envio);
		}

		return envios;
	}

}
